home *** CD-ROM | disk | FTP | other *** search
- Path: lrz-muenchen.de!news
- From: watzka@stat.uni-muenchen.de (Kurt Watzka)
- Newsgroups: comp.lang.c
- Subject: Re: (no subject)
- Date: 21 Apr 1996 20:20:17 GMT
- Organization: Leibniz-Rechenzentrum, Muenchen (Germany)
- Distribution: world
- Message-ID: <4le5a1$lg7@sparcserver.lrz-muenchen.de>
- References: <4le339$95a@ss.netgate.net>
- NNTP-Posting-Host: sun2.lrz-muenchen.de
-
- Tamara Johnson <malihini@netgate.net> writes:
-
- >/* Problem: Possible to pass a whole struct to
- > a function?
-
- > Requirement: create a function that will
- > printf a union regardless of type (using a flag)
- > using one struct containing the union and flag
- > (and etc.).
-
- > Don't need the solution, just need help passing the
- > the struct and how to printf (point to?) individual
- > elements within. I *think* I can get the rest of it */
-
- Have you actually tried to pass the struct to the function and
- access its members as you would access them anywhere else. If
- this does _not_ work, you are using an outdated version of a
- C compiler, because this method is "allowed" by a language
- definition dating back to the late 80s.
-
- >#include <stdlib.h>
- >#include <stdio.h>
- >#include <string.h>
-
- >void Function1( void *P1, void *P2);
- >void Function2( void *P1);
-
-
- > /* main ----------------------------- */
- > void main()
-
- I will not comment on this.
-
- > {
- > union tag_1{
- > float f;
- > int i;
- > char string[5];
- > double d;
- > };
-
- > struct tag_2{
- > union tag_1 Union;
- > int flag;
- > }Flag, *fP;
-
- > /* stuff to figure out if it's working to this point */
- > Flag.flag=3;
- > Flag.Union.f=5.3456;
- > /* conversion from 'const double '
- > to 'float ', possible loss of data
- > NOTE: works ok */
- > Flag.Union.d=78.9631;
-
- You cannot do this with a union and expect the float field to
- have a meaningful value after this assignment. Once you
- assign a value to the double field, you _must_ consider all
- other fields to be undefined in standard C.
-
- > Flag.Union.i=31;
- > strcpy(Flag.Union.string,"red");
-
- > printf("main() Flag.Union.string: %s\n",
- > Flag.Union.string);
- > printf("main() Flag.Union.i : %i\n", Flag.Union.i);
- > printf("main() Flag.Union.f : %f\n", Flag.Union.f);
- > printf("main() Flag.Union.d : %f\n", Flag.Union.d);
-
- > printf("main() Flag.flag : %i\n", Flag.flag);
-
- > /* end of stuff - is working when Function2 is deleted.
- > Of course, whatever union member is initialized last
- > is the one that follows thru, others will be
- > essentially garbage */
-
- > Function1(Flag.Union.string, Flag.flag); /* Function1'
- > :pointer mismatch for actual parameter 2
- > NOTE: but appears to be functioning ok
- > when Function2 deleted.
- > except passing individual elements,
- > need to pass the whole struct */
-
- Note that "Flag.flag" is an int, according to your definitions.
-
- > /*
- > Function2(fP);
-
- "fp" is an uninitialized pointer, at least I failed to see an
- assignment to that pointer. Using it may lead to interesting
- results.
-
- Try inserting
-
- fp = &Flag;
-
- before you call Function2.
-
- > */
- > }
- > /* Function1 ------------------------------ */
- >
- > void Function1( void *P1, void *P2)
- > {
-
- > printf("Function1 P1: %s\n", ( (char *)P1));
- > printf("Function1 P2: %i\n", ( (int *)P2));
- >
- > }
-
- This function is called with a pointer to the string literal "red"
- for "P1" and the integer 3 for "P2". You could successfully print
- p1 with
-
- printf("Function1 P1: %s\n", P1);
-
- but I hope that telling you the whole treatment of the second formal
- parameter works by mere chance does not turn it into a bug of the
- "Schroedinger" class. The function expects a void *, but you pass it
- the value 3. This is an undefined conversion. To printf(), you promise
- that you will pass an int, but in fact you pass a pointer to int.
-
- > /* Function2
- >
- > void Function2( void *P1) /*NOTE: not working
-
- You know more about this function that you are willing to tell your
- compiler about it. The argument is a "struct tag_2 *", and if you
- want to treat is as a such, either define Function2() as
-
- void Function2(struct tag_2 *P1)
-
- or cast the void pointer passed to Function2() to a "struct tag_2 *".
-
- To do this successfully, both the caller and the callee will have to
- have access to the definition of a "struct tag_2".
-
- > {
- > /*
- > printf("Function2 output:\n %s\n",
- > ( (char *)P1->tag_1));
-
- It is hard to figure what you want to do with that statement. The
- only time _I_ saw "tag_1" was during the definition of an enumerated
- type, so it is probably not the same "tag_1" that you use in this
- statement.
-
- >
- > printf("Function2\n");
- > if(( (char *)P1).flag==3) /* left of '.f' must have
- > struct/union type
- > NOTE: not working
-
- A "char *" usually does not have a "flag" element. If you insist on
- passing "void *", and nothing but "void *" as function arguments,
- and if you pass a vaild pointer to a "struct tag2" to this function,
- what you want seems to be
-
- if (((struct tag2 *)P1)->flag == 3)
-
- > printf("Function2 output:\n %s\n",
- > ( (char *)P1->Union.string));
- > /* left of '->Union' must point to
- > struct/union
- > NOTE: not working
- > }
-
-
- > /* ------------------ OUTPUT ---------------------------
- > main() Flag.Union.string: red
- > main() Flag.Union.i : 6579570
- > main() Flag.Union.f : 0.000000
- > main() Flag.Union.d : 78.963074
- > main() Flag.flag : 3
- > Function1 P1: red
- > Function1 P2: 3
- >
-
- Since the code you posted does not even compile, I wonder how you
- got that "OUTPUT".
-
- Kurt
- --
- | Kurt Watzka Phone : +49-89-2180-6254
- | watzka@stat.uni-muenchen.de
-